/*
 * Copyright (C) 2019 ~ 2022 UnionTech Software Technology Co., Ltd.
 *
 * Author:     zhangbingyi <zhangbingyi@uniontech.com>
 *
 * Maintainer: zhangbingyi <zhangbingyi@uniontech.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "exefilesprotectionmodel.h"
#include "common.h"
#include "invokers/invokerfactory.h"

#include <QCoreApplication>
#include <QDebug>

ExeFilesProtectionModel::ExeFilesProtectionModel(QObject *parent)
    : QObject(parent)
    , m_monitorInvoker(nullptr)
    , m_exeFilesDBusInter(nullptr)
{
    // 向qt注册用于dbus返回解析的数据结构类型
    registerExeFilesInfoMetaType();
    registerExeFilesInfoListMetaType();

    int pid = QString::number(QCoreApplication::applicationPid()).toInt();
    QDBusVariant dbusVar(pid);
    m_sessionVar.setValue(dbusVar);
    m_monitorInvoker = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.MonitorNetFlow",
                                                                   "/com/deepin/defender/MonitorNetFlow",
                                                                   "com.deepin.defender.MonitorNetFlow",
                                                                   ConnectType::SYSTEM, this);
    m_monitorInvoker->Connect("NotifyQueryExeFilesList", this, SLOT(acceptExeFilesList()));

    m_exeFilesDBusInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.daemon.ACL",
                                                                      "/org/desktopspec/Guard/Integrity1",
                                                                      "org.desktopspec.GuardIntegrity1",
                                                                      ConnectType::SYSTEM, this);
}

ExeFilesProtectionModel::~ExeFilesProtectionModel()
{
}

// 获取执行保护模式
int ExeFilesProtectionModel::getExeFilesMode()
{
    int nExeFilesMode = 0;
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_exeFilesDBusInter, DBUS_PROPERTY_INVOKER_NAME, "Mode");
    if (QDBusMessage::MessageType::ErrorMessage == msg.type()) {
        qDebug() << Q_FUNC_INFO << msg.errorMessage();
    } else {
        QVariant ret = msg.arguments().first();
        // 将QDbusVariant转成QVariant
        ret = Utils::checkAndTransQDbusVarIntoQVar(ret);
        nExeFilesMode = ret.toInt();
    }
    return nExeFilesMode;
}

// 设置执行保护模式
void ExeFilesProtectionModel::setExeFilesMode(int mode)
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_exeFilesDBusInter, "SetMode", m_sessionVar, mode);
    if (!msg.errorMessage().isEmpty() || !msg.errorName().isEmpty()) {
        qDebug() << Q_FUNC_INFO << msg.errorMessage();
    }
}

// 查询执行保护列表
void ExeFilesProtectionModel::queryExeFilesList()
{
    DBUS_NOBLOCK_INVOKE(m_monitorInvoker, "RequestExeFilesList");
}

// 同步执行保护查询
void ExeFilesProtectionModel::acceptExeFilesList()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_exeFilesDBusInter, "List", m_sessionVar, 0, 0);

    if (msg.errorMessage().isEmpty() && msg.errorName().isEmpty()) {
        QDBusArgument arg = msg.arguments().at(1).value<QDBusArgument>();
        QList<ExeFilesInfo> datas;
        arg >> datas;
        Q_EMIT sendExeFilesList(datas);
    } else {
        qDebug() << Q_FUNC_INFO << msg.errorMessage();
    }
}

// 添加执行文件
void ExeFilesProtectionModel::addExeFile(const QString &file)
{
    QStringList list;
    list.append(file);
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_exeFilesDBusInter, "Add", m_sessionVar, list);
    if (msg.errorMessage().isEmpty() && msg.errorName().isEmpty()) {
        queryExeFilesList();
    } else {
        qDebug() << Q_FUNC_INFO << msg.errorMessage();
    }
}

// 信任当前状态
void ExeFilesProtectionModel::trustCurrentStatus(const QString &file)
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_exeFilesDBusInter, "Trust", m_sessionVar, file);
    if (msg.errorMessage().isEmpty() && msg.errorName().isEmpty()) {
        queryExeFilesList();
    } else {
        qDebug() << Q_FUNC_INFO << msg.errorMessage();
    }
}

// 删除保护文件
void ExeFilesProtectionModel::deleteTrustFiles(QStringList sFilePaths)
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_exeFilesDBusInter, "Remove", m_sessionVar, sFilePaths);
    if (msg.errorMessage().isEmpty() && msg.errorName().isEmpty()) {
        queryExeFilesList();
    } else {
        qDebug() << Q_FUNC_INFO << msg.errorMessage();
    }
}
